home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Contributed / SpriteWorld / SpriteWorld Files / Utils / SWDitherDown.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-06  |  6.2 KB  |  219 lines  |  [TEXT/CWIE]

  1. #ifndef __RESOURCES__
  2. #include <Resources.h>
  3. #endif
  4.  
  5. #include <QDOffScreen.h>
  6. #include <SpriteWorldUtils.h>
  7. #include <SWDitherDown.h>
  8.  
  9. /*
  10.     
  11.     If you create a game using 8-bit graphics, and you:
  12.     A) want the game to be usable on a less-than-8-bit system, although 
  13.     B) not usable on 68000 Macs, and 
  14.     C) rather than creating new graphics for it, want to dither down the 8-bit graphics,
  15.     then these routines will help you out.
  16.  
  17.     Note B) above; SpriteWorld requires Color QuickDraw, which in turn requires a 68020 or 
  18.     higher processor, so your game still won't be playable on a Mac Plus, SE, Mac Classic, etc. 
  19.     These routines use the CopyBits ditherCopy mode. This provides results far superior to
  20.     what you  get from simply using DrawPicture() to draw an 8-bit PICT to a lower-depth GWorld.
  21.     The results are usually still pretty ugly, however.
  22.  
  23.     Warning! no error handling in these routines. Errors might be not enough memory
  24.     to create the GWorlds or to load the pict/cicn or, of course, invalid resID's.
  25.  
  26.  
  27.  
  28.     DitherDownPict; use with either a Sprite made with SWCreateSpriteFromPictResource
  29.     or with SWCreateSpriteFromSinglePict. In the case of SWCreateSpriteFromPictResource,
  30.     pictResID is the ID of a Frame's pict, and destGWorld would be the Frame's framePort:
  31.     
  32.     for (frame = 0; frame < maxFrames; frame++)
  33.     {
  34.         theFrameP = theSprite->frameArray[frame];
  35.         
  36.         DitherDownPict( pictResID+frame, theFrameP->framePort );
  37.     }
  38.     
  39.     For SWCreateSpriteFromSinglePict, you'd just pass the multi-frame pict's ID, and
  40.     the shared GWorld of the Sprite:
  41.     
  42.     DitherDownPict( pictResID, theSprite->sharedPictGWorld );
  43.     
  44.     If you're dithering down tiles, you just have to call this once for a single-pict
  45.     group of tiles. For the destGWorld, use the framePort of any one of the tiles:
  46.     
  47.     DitherDownPict( pictResID, theTile->framePort );
  48.     
  49. */
  50.     
  51. /******************** DitherDownPict ********************/
  52. void DitherDownPict( short pictResID, GWorldPtr destGWorld )
  53. {
  54.  
  55.     GWorldPtr            picGWld,
  56.                         oldGWld;
  57.     GDHandle            oldGDH;
  58.     Rect                picRect;
  59.     PicHandle            thePic;
  60.     GWorldFlags            pixelState;
  61.  
  62.  
  63.     GetGWorld( &oldGWld, &oldGDH );
  64.     
  65.     thePic = GetPicture( pictResID );
  66.     picRect = (**(thePic)).picFrame;
  67.     OffsetRect( &picRect, 0-picRect.left, 0-picRect.top );
  68.     
  69.     (void)NewGWorld( &picGWld, 8, &picRect, nil, nil, 0 );
  70.     (void)LockPixels( GetGWorldPixMap( picGWld ));
  71.     SetGWorld( picGWld, NULL );
  72.     
  73.     DrawPicture( thePic, &picRect );
  74.     ReleaseResource( (Handle)thePic );
  75.     
  76.     pixelState = GetPixelsState( GetGWorldPixMap( destGWorld ));
  77.     (void)LockPixels( GetGWorldPixMap( destGWorld ));
  78.     SetGWorld( destGWorld, NULL );
  79.     CopyBits ( (BitMap*)*GetGWorldPixMap( picGWld ),
  80.             (BitMap*)*GetGWorldPixMap( destGWorld ),
  81.             &picRect,  
  82.             &picRect, ditherCopy, nil);
  83.     
  84.     SetPixelsState( GetGWorldPixMap( destGWorld ), pixelState );
  85.     DisposeGWorld( picGWld );
  86.     SetGWorld( oldGWld, oldGDH );
  87. }
  88.  
  89.  
  90. /*
  91.     This routine is for when you have a self-masking Sprite created from an 8-bit PICT,
  92.     and want to use it on a lower-depth screen. Using the 8-bit PICT as a pixel mask may
  93.     not work correctly unless you convert the mask afterwards with this. This is called
  94.     much like DitherDownPict, except that the maskPort is passed instead of the framePort:
  95.     
  96.     for (frame = 0; frame < maxFrames; frame++)
  97.     {
  98.         theFrameP = theSprite->frameArray[frame];
  99.         
  100.         LowerMaskDepth( pictResID+frame, theFrameP->maskPort );
  101.     }
  102.     or:
  103.     LowerMaskDepth( pictResID, theSprite->sharedMaskGWorld );
  104. */
  105.     
  106. /******************** LowerMaskDepth ********************/
  107. void LowerMaskDepth( short pictResID, GWorldPtr destGWorld )
  108. {
  109.     GWorldPtr            picGWld,
  110.                         oldGWld;
  111.     GDHandle            oldGDH;
  112.     Rect                picRect;
  113.     PicHandle            thePic;
  114.     GWorldFlags            pixelState;
  115.  
  116.  
  117.     if ( destGWorld == NULL )
  118.         return;
  119.         
  120.     GetGWorld( &oldGWld, &oldGDH );
  121.     
  122.     thePic = GetPicture( pictResID );
  123.     picRect = (**(thePic)).picFrame;
  124.     OffsetRect( &picRect, 0-picRect.left, 0-picRect.top );
  125.     
  126.     (void)NewGWorld( &picGWld, 8, &picRect, nil, nil, 0 );
  127.     (void)LockPixels( GetGWorldPixMap( picGWld ));
  128.     SetGWorld( picGWld, NULL );
  129.     
  130.     DrawPicture( thePic, &picRect );
  131.     ReleaseResource( (Handle)thePic );
  132.  
  133.     SWBlackenGWorld( picGWld );
  134.  
  135.     pixelState = GetPixelsState( GetGWorldPixMap( destGWorld ));
  136.  
  137.     (void)LockPixels( GetGWorldPixMap( destGWorld ));
  138.     SetGWorld( destGWorld, NULL );
  139.     CopyBits ( (BitMap*)*GetGWorldPixMap( picGWld ),
  140.             (BitMap*)*GetGWorldPixMap( destGWorld ),
  141.             &picRect,  
  142.             &picRect, srcCopy, nil);
  143.     InvertRect( &picRect );
  144.  
  145.     SetPixelsState( GetGWorldPixMap( destGWorld ), pixelState );
  146.  
  147.     DisposeGWorld( picGWld );
  148.     SetGWorld( oldGWld, oldGDH );
  149. }
  150.  
  151.  
  152.  
  153. /*
  154.     DitherDownCicn; use with a Sprite made with SWCreateSpriteFromCicnResource. 
  155.     cicnResID is the ID of a Frame's CIcon, and destGWorld is the Frame's framePort:
  156.     
  157.     for (frame = 0; frame < maxFrames; frame++)
  158.     {
  159.         theFrameP = theSprite->frameArray[frame];
  160.         
  161.         DitherDownCicn( cicnResID+frame, theFrameP->framePort );
  162.     }
  163.     
  164.     Can also be used for tiles made from CIcons:
  165.     
  166.     theFrameP = mySpriteWorldP->tileFrameArray[tileID];
  167.     DitherDownCicn( cicnResID, theFrameP->framePort );
  168.     
  169.     Note that this dithers down the 8-bit color image of the CIcon; it ignores the CIcon's
  170.     black & white image, if any.
  171. */
  172.  
  173. /******************** DitherDownCicn ********************/
  174. void DitherDownCicn( short cicnResID, GWorldPtr destGWorld )
  175. {
  176.  
  177.     GWorldPtr            picGWld,
  178.                         oldGWld;
  179.     GDHandle            oldGDH;
  180.     Rect                frameRect;
  181.     CIconHandle            cIconH;
  182.     GWorldFlags            pixelState;
  183.     
  184.  
  185.     GetGWorld( &oldGWld, &oldGDH );
  186.     
  187.     
  188.     cIconH = GetCIcon( cicnResID );
  189.  
  190.     HLock((Handle)cIconH);
  191.     frameRect = (**cIconH).iconPMap.bounds;
  192.             
  193.     (void)NewGWorld( &picGWld, 8, &frameRect, nil, nil, 0 );
  194.     (void)LockPixels( GetGWorldPixMap( picGWld ));
  195.     SetGWorld( picGWld, NULL );
  196.     
  197.     (**cIconH).iconPMap.baseAddr = *(**cIconH).iconData;                
  198.     CopyBits( (BitMap*)(&((**cIconH).iconPMap)),
  199.         (BitMap*)*GetGWorldPixMap( picGWld ), 
  200.         &frameRect,
  201.         &frameRect, srcCopy, nil);
  202.     DisposeCIcon(cIconH);
  203.     
  204.     pixelState = GetPixelsState( GetGWorldPixMap( destGWorld ));
  205.     (void)LockPixels( GetGWorldPixMap( destGWorld ));
  206.     SetGWorld( destGWorld, NULL );
  207.     CopyBits ( (BitMap*)*GetGWorldPixMap( picGWld ),
  208.             (BitMap*)*GetGWorldPixMap( destGWorld ),
  209.             &frameRect,  
  210.             &frameRect, ditherCopy, nil);
  211.     SetPixelsState( GetGWorldPixMap( destGWorld ), pixelState );
  212.     
  213.     DisposeGWorld( picGWld );
  214.     SetGWorld( oldGWld, oldGDH );
  215. }
  216.  
  217.  
  218.  
  219.